/* global TextDecoder */
'use strict'
import EventEmitter from '../EventEmitter'
import Http from '../http'
import Client from '../client'
import RoomData from '../roomdata'
export default class PandaRoom extends EventEmitter {
  constructor (roomId) {
    super()
    this.roomId = roomId
    this.rid = 'rid'
    this.appid = 'appId'
    this.ts = 'ts'
    this.sign = ''
    this.authtype = ''
    this.count = 0
    this.k = '1'
    this.t = '300'
    this.info = {}
    this.gifts = {}
    this.count = 0
    this.fans = 0
    this.timer = null
    this.data = new RoomData('panda', roomId)
    this.data.on('roomClose', this.onRoomClose.bind(this))
    this.isInit = false
    this.http = new Http()
    this.http.on('data', this.onInfo.bind(this))
    this.http.on('error', () => {
      this.emit('init', null)
    })
    this._getGift()
  }
  onRoomClose () {
    this.remove()
  }
  remove () {
    this.data.close()
    clearTimeout(this.timer)
    this.client.close()
  }
  _getGift () {
    let http = new Http()
    http.on('data', (info) => {
      if (!info || info.errno !== 0) {
        this.emit('init', null)
        return
      }
      this.gifts = info.data.items
      this._getFans()
    })
    http.on('error', () => {
      this.emit('init', null)
    })
    http.get(`http://mall.panda.tv/ajax_gift_gifts_get?roomid=${this.roomId}&__plat=pc_web`)
  }
  _getFans () {
    let http = new Http()
    http.on('data', (info) => {
      if (!info || info.errno !== 0) {
        this.emit('init', null)
        return
      }
      this.fans = info.data.fans
      this._getInfo()
    })
    http.on('error', () => {
      this.emit('init', null)
    })
    http.get(`http://www.panda.tv/room_followinfo?roomid=${this.roomId}&_=${new Date().getTime()}`)
  }
  _getInfo () {
    this.http.get(`http://www.panda.tv/api_room_v2?roomid=${this.roomId}&pub_key=&__plat=pc_web&_=${new Date().getTime()}`)
  }
  onInfo (info) {
    if (info && info.errno === 0) {
      let data = info.data
      let obj = {
        data: {
          avatar: data.hostinfo.avatar,
          room_name: data.roominfo.name,
          room_id: data.roominfo.id,
          owner_name: data.hostinfo.name,
          online: data.roominfo.person_num,
          owner_weight: '0',
          fans_num: this.fans,
          room_status: data.roominfo.status === '2' ? '1' : '2',
          gift: [{
            id: '1',
            pc: '1',
            type: '1',
            name: '竹子'
          }]
        },
        error: 0
      }
      for (let i = 0; i < this.gifts.length; i++) {
        obj.data.gift.push({
          id: this.gifts[i].id,
          pc: this.gifts[i].price,
          type: '2',
          name: this.gifts[i].name
        })
      }
      this.info = obj
      if (!this.isInit) {
        this.data.initRoom(this.info.data)
        this.login()
        this.isInit = true
        this.emit('init', this.info.data.room_id)
      } else {
        this.data.update(this.info.data)
      }
    } else {
      if (!this.isInit) {
        this.emit('init', null)
      }
    }
  }
  login () {
    let http = new Http()
    http.on('error', () => {
      this.emit('error')
    })
    http.on('data', (info) => {
      if (!info || info.errno !== 0) {
        this.emit('error')
        return
      }
      if (info.data.appid) {
        let addr = info.data.chat_addr_list[0].split(':')
        let ip = addr[0]
        let port = parseInt(addr[1], 10)
        this.rid = info.data.rid
        this.appid = info.data.appid
        this.ts = info.data.ts
        this.sign = info.data.sign
        this.authtype = info.data.authType
        this.client = new Client(ip, port)
        this.client.on('connect', this.onConnect.bind(this))
        this.client.on('data', this.onData.bind(this))
      } else {
        let rid = info.data.rid
        let roomid = info.data.roomid
        let sign = info.data.sign
        let ts = info.data.ts
        http.get(`http://api.homer.panda.tv/chatroom/getinfo?rid=${rid}&roomid=${roomid}&retry=0&sign=${sign}&ts=${ts}&_=${new Date().getTime()}`)
      }
    })
    http.get(`http://www.panda.tv/ajax_chatroom?roomid=${this.roomId}&_=${new Date().getTime()}`)
  }
  keepAlive () {
    this.timer = setInterval(() => {
      let buf = new Uint8Array([0x00, 0x06, 0x00, 0x00])
      this.client.send(buf.buffer)
      this._getInfo()
    }, 60 * 1000)
  }
  onConnect () {
    let msg = `u:${this.rid}@${this.appid}\nk:${this.k}\nt:${this.t}\nts:${this.ts}\nsign:${this.sign}\nauthtype:${this.authtype}`
    var buf = new ArrayBuffer(msg.length * 2 + 10)
    var dataview = new DataView(buf)
    for (var i = 0, strLen = msg.length; i < strLen; i++) {
      dataview.setUint16(6 + i, msg.charCodeAt(i), true)
    }
    dataview.setUint16(0, 6, false)
    dataview.setUint16(2, 2, false)
    dataview.setUint16(4, msg.length, false)
    dataview.setUint16(msg.length * 2 + 6, 6, false)
    dataview.setUint16(msg.length * 2 + 8, 0, false)
    this.client.send(buf)
    this.keepAlive()
  }
  onData (info) {
    let dataview = new DataView(info.data)
    if (dataview.byteLength > 26) {
      let decoder = new TextDecoder('utf8')
      let total = dataview.getUint32(11, false)
      let readLength = 0
      let readCount = 11 + 4
      do {
        readCount += 12
        let length = dataview.getUint32(readCount, false)
        readLength += length
        readCount += 4
        let bodyview = new DataView(info.data, readCount, length)
        let bodyStr = decoder.decode(bodyview)
        let obj = JSON.parse(bodyStr)
        if (obj.data.to.toroom === this.roomId && obj.data.from.rid !== '-1') {
          let msg = this.convert(obj)
          this.data[msg.type](msg)
        }
        readCount += length
      } while (total > readLength + 64)
    }
  }
  convert (info) {
    let msg = {}
    var date = new Date()
    let data = info.data
    let from = data.from
    let type = info.type
    switch (type) {
      case '1':
        msg.type = 'chatmsg'
        msg.txt = data.content
        break
      case '206':
        msg.type = 'dgb'
        msg.gfid = '1'
        msg.count = data.content
        break
      case '306':
        msg.type = 'dgb'
        msg.gfid = data.content.id
        break
    }
    msg.uid = from.rid
    msg.level = from.level || '0'
    msg.nn = from.nickName
    msg.rid = data.to.toroom
    msg.serverdate = date.getHours() + ':' + date.getMinutes()
    return msg
  }
}
